package com.ja.rfid.controller;

import com.ja.rfid.common.R;
import com.ja.rfid.dto.WriteDto;
import com.ja.rfid.service.RfidService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: 供应商提供的可视化操作界面
 * @author: hubin
 * @date: 2022/10/27 14:56
 */
@Slf4j
@RestController
@RequestMapping("/rfid")
public class RfidController {

    @Autowired
    private RfidService rfidService;

    /**
     * 连接tcp
     *
     * @return
     */
    @GetMapping("/doOpen")
    public R doOpen(@RequestParam("number") Integer number) {
        log.info("连接tcp, number:{}", number);
        rfidService.doClose(number);
        if (rfidService.doOpen(number)) {
            return R.ok("连接成功");
        }
        return R.error("连接失败");
    }

    /**
     * 关闭连接
     *
     * @return
     */
    @GetMapping("/doClose")
    public R doClose(@RequestParam("number") Integer number) {
        log.info("关闭tcp连接, number:{}", number);
        if (rfidService.doClose(number)) {
            return R.ok("关闭成功");
        }
        return R.error("关闭失败");
    }

    /**
     * 应答模式-查询
     * 读多个标签的数据
     *
     * @return
     */
    @GetMapping("/doQueryBatch")
    public R doQueryBatch(@RequestParam("number") Integer number) {
        log.info("读多个标签的数据, number:{}", number);
        R r = this.doOpen(number);
        if (r.getCode() != 0) {
            return r;
        }
        try {
            List<String> queryData = rfidService.doQueryBatch(number);
            if (CollectionUtils.isEmpty(queryData)) {
                return R.error("未读到标签数据！");
            }
            List<String> collect = queryData.stream().map(it -> it.replaceAll("^(0+)", "")).collect(Collectors.toList());
            return R.ok().put("data", collect);

        } finally {
            this.doClose(number);
        }
    }

    /**
     * 应答模式-查询
     * 读单个标签的数据
     *
     * @return
     */
    @GetMapping("/doQuery")
    public R doQuery(@RequestParam("number") Integer number) {
        log.info("读单个标签的数据, number:{}", number);
        R r = this.doOpen(number);
        if (r.getCode() != 0) {
            return r;
        }
        try {
            List<String> queryData = rfidService.doQuery(number);
            if (CollectionUtils.isEmpty(queryData)) {
                return R.error("未读到标签数据！");
            }
            if (queryData.size() > 1) {
                return R.error("只能读单个标签！");
            }
            List<String> collect = queryData.stream().map(it -> it.replaceAll("^(0+)", "")).collect(Collectors.toList());
            return R.ok().put("data", collect);

        } finally {
            this.doClose(number);
        }
    }

    /**
     * 应答模式-写卡操作(1号机器写卡)
     * 返回值0表示写卡中，其他表示报错
     *
     * @return
     */
    @PostMapping("/doWrite")
    public R doWrite(@RequestBody @Validated WriteDto writeDto) {
        log.info("写标签的数据, writeDto:{}", writeDto);
        String newEpc = writeDto.getNewEpc();
        R r = this.doOpen(0);
        if (r.getCode() != 0) {
            return r;
        }
        try {
            //查询标签数据
            List<String> oldEpc = rfidService.doQuery(0);
            if (CollectionUtils.isEmpty(oldEpc)) {
                return R.error("未读到标签数据！");
            }
            if (oldEpc.size() > 1) {
                return R.error("写卡操作时不能放多个标签在机器上！");
            }
            //长度
            int oldEpcLength = oldEpc.get(0).length();
            //新数据为 原标签的长度，不足补零.
            try {
                newEpc = String.format("%0" + (oldEpcLength) + "d", Long.parseLong(newEpc));
            } catch (NumberFormatException e) {
                return R.error("写卡失败,新数据必须是数字！");
            }
            Boolean isWrite = rfidService.doWrite(oldEpc.get(0), newEpc);
            if (isWrite) {
                return R.ok("写卡成功！");
            }
            return R.error("写卡失败！");

        } finally {
            this.doClose(0);
        }
    }


}
